package com.bit.cfdi.web.vm.wizard;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.zkoss.bind.BindContext;
import org.zkoss.bind.BindUtils;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.GlobalCommand;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.util.media.Media;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.UploadEvent;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Window;

import com.bit.cfdi.web.constants.CFDIConstants;
import com.bit.cfdi.web.domain.Estado;
import com.bit.cfdi.web.domain.Pais;
import com.bit.cfdi.web.services.EstadoService;
import com.bit.cfdi.web.services.PaisService;
import com.bit.cfdi.web.vm.negocio.WrapperGiros;

@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
public class Paso2ViewModel {	
	
	private Logger log = LogManager.getLogger(this.getClass().getName());	
	private Window window;
	private WizardViewParserPaso2 wizardViewParser;
	private String lblCer;
	private String lblFechaCad;
	private String urlCer;	
	private String urlKey;
	private String txtPasswordKey;
	private Boolean chkCopiarDireccion;
	
	private String paisFiscal;
	private String estadoFiscal;
	private List<String> paisesFiscales;
	private List<String> estadosFiscales;
	private List<Estado> edoListFiscales;
	
	private String paisSucursal;
	private String estadoSucursal;
	private List<String> paisesSucursal;
	private List<String> estadosSucursal;
	private List<Estado> edoListSucursal;
	
	//--
	private String businessNameMsjError;
	private String passKeyMsjError;
	private String cerMsjError;
	private String keyMsjError;
	private String msjErrorRfc;
	private String msjErrorRazonSocial;
	private String msjErrorCalleFiscal;
	private String msjErrorCPFiscal;
	private String msjErrorMunicipioFiscal;	
	private String msjErrorPaisFiscal;
	private String msjErrorEstadoFiscal;
	private String msjErrorCalleSucursal;
	private String msjErrorCPSucursal;
	private String msjErrorMunicipioSucursal;
	private String msjErrorPaisSucursal;
	private String msjErrorEstadoSucursal;
	private String msjErrorNameSucursal;
	//--
	private List<WrapperGiros> listGiros;
				
	@WireVariable private PaisService paisService;
	@WireVariable private EstadoService estadoService;
	//@WireVariable private CertificateUtils certificateUtils;	
	private String nameGiros;
	
	@Init
	public void init()
	{
		wizardViewParser = new WizardViewParserPaso2();			
		retrieveInitialBusinessInfo();				
		chkCopiarDireccion = false;																									
	}
	
	/**
	*--- 	GETTERS AND SETTERS
	*/
	
	public WizardViewParserPaso2 getWizardViewParser() {
		return wizardViewParser;
	}

	public void setWizardViewParser(WizardViewParserPaso2 wizardViewParser) {
		this.wizardViewParser = wizardViewParser;
	}
	
	public Boolean getChkCopiarDireccion() {
		return chkCopiarDireccion;
	}

	public void setChkCopiarDireccion(Boolean chkCopiarDireccion) {
		this.chkCopiarDireccion = chkCopiarDireccion;
	}
	
	public String getLblCer() {
		return lblCer;
	}

	public String getLblFechaCad() {
		return lblFechaCad;
	}

	public String getUrlCer() {
		return urlCer;
	}

	public String getUrlKey() {
		return urlKey;
	}

	public String getTxtPasswordKey() {
		return txtPasswordKey;
	}

	public void setTxtPasswordKey(String txtPasswordKey) {
		this.txtPasswordKey = txtPasswordKey;
	}

	public String getBusinessNameMsjError() {
		return businessNameMsjError;
	}
	//
	
	public String getPassKeyMsjError() {
		return passKeyMsjError;
	}

	public String getCerMsjError() {
		return cerMsjError;
	}

	public String getKeyMsjError() {
		return keyMsjError;
	}	
		
	public String getMsjErrorRfc() {
		return msjErrorRfc;
	}

	public String getMsjErrorCalleFiscal() {
		return msjErrorCalleFiscal;
	}

	public String getMsjErrorCPFiscal() {
		return msjErrorCPFiscal;
	}

	public String getMsjErrorMunicipioFiscal() {
		return msjErrorMunicipioFiscal;
	}

	public String getMsjErrorPaisFiscal() {
		return msjErrorPaisFiscal;
	}

	public String getMsjErrorEstadoFiscal() {
		return msjErrorEstadoFiscal;
	}

	public String getMsjErrorCalleSucursal() {
		return msjErrorCalleSucursal;
	}

	public String getMsjErrorCPSucursal() {
		return msjErrorCPSucursal;
	}

	public String getMsjErrorMunicipioSucursal() {
		return msjErrorMunicipioSucursal;
	}

	public String getMsjErrorPaisSucursal() {
		return msjErrorPaisSucursal;
	}

	public String getMsjErrorEstadoSucursal() {
		return msjErrorEstadoSucursal;
	}

	public String getMsjErrorRazonSocial() {
		return msjErrorRazonSocial;
	}
	
	public String getMsjErrorNameSucursal() {
		return msjErrorNameSucursal;
	}

	//
	public List<String> getPaisesFiscales()
	{	
		paisesFiscales = new ArrayList<String>();		
		for(Pais p: paisService.getAll()){
			paisesFiscales.add(p.getPais());
		}
		return paisesFiscales;
	}
	
	public List<String> getEstadosFiscales(){	
		estadosFiscales = new ArrayList<String>();						
		edoListFiscales = estadoService.getEstadosByPais(getPaisFiscal());
		if(null!=edoListFiscales && edoListFiscales.size()>0)
			for(Estado e: edoListFiscales){
				estadosFiscales.add(e.getEstado());
			}	
		return  estadosFiscales;
	}
	
	public String getPaisFiscal() {
		return paisFiscal;
	}
	@NotifyChange({"estadosFiscales"})
	public void setPaisFiscal(String paisFiscal) {
		wizardViewParser.setPaisFiscal(null);
		this.paisFiscal = paisFiscal;
		wizardViewParser.setPaisFiscal(paisFiscal);
	}
	
	public String getEstadoFiscal() {
		return estadoFiscal;
	}

	public void setEstadoFiscal(String estadoFiscal) {
		wizardViewParser.setEstadoFiscal(null);
		this.estadoFiscal = estadoFiscal;
		wizardViewParser.setEstadoFiscal(estadoFiscal);
	}
	//--
	public List<String> getPaisesSucursal()
	{	
		paisesSucursal = new ArrayList<String>();		
		for(Pais p: paisService.getAll()){
			paisesSucursal.add(p.getPais());
		}
		return paisesSucursal;
	}
	
	public List<String> getEstadosSucursal(){	
		estadosSucursal = new ArrayList<String>();						
		edoListSucursal = estadoService.getEstadosByPais(getPaisSucursal());
		if(null!=edoListSucursal && edoListSucursal.size()>0)
			for(Estado e: edoListSucursal){
				estadosSucursal.add(e.getEstado());
			}	
		return  estadosSucursal;
	}
	
	public String getPaisSucursal() {
		return paisSucursal;
	}
	
	@NotifyChange({"estadosSucursal"})
	public void setPaisSucursal(String paisSucursal) {
		wizardViewParser.setPaisSucursal(null);
		this.paisSucursal = paisSucursal;
		wizardViewParser.setPaisSucursal(paisSucursal);
	}
	
	public String getEstadoSucursal() {
		return estadoSucursal;
	}

	public void setEstadoSucursal(String estadoSucursal) {
		wizardViewParser.setEstadoSucursal(null);
		this.estadoSucursal = estadoSucursal;
		wizardViewParser.setEstadoSucursal(estadoSucursal);
	}
	
	public String getNameGiros() {
		return nameGiros;
	}

	public void setNameGiros(String nameGiros) {
		this.nameGiros = nameGiros;
	}

	//---
	@Command
	@NotifyChange({"wizardViewParser"})	
	public void copiarDireccionFiscal()
	{		
		if(chkCopiarDireccion == true)
		{					
			wizardViewParser.setCalleSucursal(wizardViewParser.getCalleFiscal());
			wizardViewParser.setNoExteriorSucursal(wizardViewParser.getNoExteriorFiscal());
			wizardViewParser.setNoInteriorSucursal(wizardViewParser.getNoInteriorFiscal());
			wizardViewParser.setColoniaSucursal(wizardViewParser.getColoniaFiscal());
			wizardViewParser.setCodigoPostalSucursal(wizardViewParser.getCodigoPostalFiscal());
			wizardViewParser.setReferenciaSucursal(wizardViewParser.getReferenciaFiscal());		
			wizardViewParser.setPaisSucursal(wizardViewParser.getPaisFiscal());
			wizardViewParser.setEstadoSucursal(wizardViewParser.getEstadoFiscal());
			wizardViewParser.setCiudadSucursal(wizardViewParser.getCiudadFiscal());
			wizardViewParser.setMunicipioSucursal(wizardViewParser.getMunicipioFiscal());
			wizardViewParser.setLocalidadSucursal(wizardViewParser.getLocalidadFiscal());
		}
		else
		{
			wizardViewParser.setCalleSucursal(null);
			wizardViewParser.setNoExteriorSucursal(null);
			wizardViewParser.setNoInteriorSucursal(null);
			wizardViewParser.setColoniaSucursal(null);
			wizardViewParser.setCodigoPostalSucursal(null);
			wizardViewParser.setReferenciaSucursal(null);
			wizardViewParser.setPaisSucursal(null);
			wizardViewParser.setEstadoSucursal(null);
			wizardViewParser.setCiudadSucursal(null);
			wizardViewParser.setMunicipioSucursal(null);
			wizardViewParser.setLocalidadSucursal(null);
		}
	}
	
	@Command
	@NotifyChange({"lblCer", "lblFechaCad", "urlCer", "wizardViewParser"})
	public void uploadCer(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx)
	{		/*
		UploadEvent upEvent = (UploadEvent) ctx.getTriggerEvent();		
		Media mediaObj = upEvent.getMedia();
		String type = mediaObj.getContentType();
		if(type.equals(CFDIConstants.CERT_FILE)) //!!Cambiar por constante
		{
			try{
				wizardViewParser.setBytesCer(mediaObj.getByteData());
				byte[] bytesCer = wizardViewParser.getBytesCer(); 
				String noCer = certificateUtils.getNumeroCetificado(bytesCer);
				Date fechaExp = certificateUtils.obtFechaExp(bytesCer);
				if(fechaExpValida(fechaExp))
				{
					SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy");					
					lblCer = "Serie del Certificado " + noCer ;
					lblFechaCad = "Caducidad del Certificado " + formato.format(fechaExp);
					wizardViewParser.setRfcFiscal(certificateUtils.obtenerRFC(bytesCer));
					urlCer = "Archivo cer válido";
				}
				else
				{
					Messagebox.show("El archivo cer seleccionado ha caducado "
						,"Error", Messagebox.OK, Messagebox.ERROR);
					dropDataCer();
				}
			}
			catch(Exception e)
			{			
				Messagebox.show("Ha ocurrido un error durante la carga del " +
				"archivo cer" + e,"Error", Messagebox.OK, Messagebox.ERROR);
				dropDataCer();
			}			
		}
		else
		{
			Messagebox.show("El archivo seleccionado no coincide con el " +
				"archivo esperado", "Error", Messagebox.OK, Messagebox.ERROR);
			dropDataCer();
		}*/
	}	
		
	@Command
	@NotifyChange({"urlKey","txtPasswordKey"})
	public void uploadKey(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx)
	{
		UploadEvent upEvent = (UploadEvent) ctx.getTriggerEvent();		
		Media mediaObjKey = upEvent.getMedia();
		String type = mediaObjKey.getContentType();	
		if(type.equals(CFDIConstants.KEY_FILE))
		{
			wizardViewParser.setBytesKey(mediaObjKey.getByteData());
			urlKey = "Archivo válido";			
		}
		else
		{			
			Messagebox.show("El archivo seleccionado no es válido"
					, "Error", Messagebox.OK, Messagebox.ERROR);
			dropDataKey();
		}
	}
	
	@Command
	@NotifyChange({"lblCer", "lblFechaCad", "urlCer", "urlKey", 
		"passKeyMsjError", "txtPasswordKey", "wizardViewParser"})
	public void limpiarCSD()
	{
		if(!(lblCer.isEmpty()))
		{
			dropDataCer();
			dropDataKey();
			wizardViewParser.setBytesCer(null);
			wizardViewParser.setBytesKey(null);
			passKeyMsjError = null;
		}		
	}
	
	@Command
	@NotifyChange({"txtPasswordKey"})
	public Boolean isValidKey()
	{		
		Boolean resul = true;/*		
		try
		{
			if((certificateUtils.isValidKey(wizardViewParser.getBytesKey(), 
				txtPasswordKey)))
			{				
				passKeyMsjError = null;
			}			
		}
		catch(Exception e)
		{
			passKeyMsjError = "El password ingresado para el key no es correcto.";
			dropDataKey();			
			resul = false;
		}*/
		return resul;
	}
	
	@Command	
	@NotifyChange({"wizardViewParser", "businessNameMsjError","passKeyMsjError", 
		"cerMsjError", "keyMsjError", "msjErrorRfc", "msjErrorRazonSocial", 
		"msjErrorCalleFiscal", "msjErrorCPFiscal", "msjErrorPaisFiscal", 
		"msjErrorEstadoFiscal", "msjErrorMunicipioFiscal", "msjErrorCalleSucursal", 
		"msjErrorCPSucursal", "msjErrorPaisSucursal", "msjErrorEstadoSucursal", 
		"msjErrorMunicipioSucursal", "msjErrorNameSucursal"})
	public void recuperarInfoCliente() {		
		if(isValidDataFormBusiness())
		{			
			sendObjWizard();														
		}
		else
		{
			return;			
		}			
	}
	
	@Command
	public void showPopUpGiros()
	{		
		Map <String, Object> objList = new HashMap<String, Object>();
		objList.put("listGiros", listGiros);			
		
		window =(Window)Executions.createComponents(
			"/home/negocio/modalWindowGiros1.zul", null, objList);
		window.doModal();						
	}
	
	@Command
	public void sendObjWizard()
	{
		Map <String, Object> objStep2 = new HashMap<String, Object>();
		objStep2.put("step2", wizardViewParser);
		BindUtils.postGlobalCommand(null, null, "assignObjStep2", objStep2);
	}
	
	private void dropDataCer()
	{			
		urlCer = "";
		lblCer = "";
		lblFechaCad = "";
		wizardViewParser.setRfcFiscal("");
	}
	
	private void dropDataKey()
	{		
		urlKey = "";
		txtPasswordKey = "";		
	}
	
	private Boolean fechaExpValida(Date fechaExp)
	{
		Boolean resultado = false;		
		Date fecha = new Date();
		if((fechaExp.compareTo(fecha) == 1) || (fechaExp.compareTo(fecha) == 0))
		{
			resultado = true;
		}				
		else
		{			
			resultado = false;
		}
		return resultado;		
	}	
	
	private Boolean isValidDataFormBusiness()
	{		
		keyMsjError = null;
		cerMsjError = null;			
		if(!validarNombreNegocio())
		{
			return false;
		}
		if(!validarCerKey())
		{
			return false;
		}
		if(!validarRFC())
		{
			return false;
		}
		if(!validarRFC())
		{
			return false;
		}
		if(!validarDireccionSucursal())
		{
			return false;
		}
		
		return true;
	}
	
	private Boolean validarNombreNegocio()
	{
		Boolean resul = true;
		if((wizardViewParser.getNombreNegocio() == null) || 
				(wizardViewParser.getNombreNegocio().equals("")))
		{			
			businessNameMsjError = "El nombre del negocio es de " +
					"caracter obligatorio";
			resul = false;
		}			
		else
		{
			if(wizardViewParser.getNombreNegocio().equals("Nombre del negocio"))
			{
				businessNameMsjError = "El texto 'Nombre del negocio' no es válido";
				resul= false;
			}	
			businessNameMsjError = null;
		}
		return resul;
	}
	
	private Boolean validarCerKey()
	{
		Boolean resul = true;
		if(((wizardViewParser.getBytesCer() != null)&&
				(wizardViewParser.getBytesKey() == null))||  
				((wizardViewParser.getBytesCer() == null)&&
				(wizardViewParser.getBytesKey() != null)))
		{						
			if(wizardViewParser.getBytesKey() != null)
			{				
				cerMsjError = "El archivo .cer es necesario si se ha elegido el " +
						"archivo .key";				
			}
			else
			{
				keyMsjError = "El archivo .key es necesario si se ha elegido el " +
						"archivo .cer";				
			}
			resul = false;			
		}
		else
		{
			if((wizardViewParser.getBytesCer() != null) && 
					(wizardViewParser.getBytesKey() != null))
			{
				resul = isValidKey();
			}
		}
		return resul;
	}
		
	private Boolean validarRFC()
	{		
		resetMsjErrorFiscal();
		Boolean resul = true;		
		if(!isNullOrEmpty(wizardViewParser.getRfcFiscal()))
		{	
			if(!wizardViewParser.getRfcFiscal().matches(CFDIConstants.RFC_PATTERN))
			{
				msjErrorRfc = "R.F.C. incorrecto.";
				resul = false;
			}
			else{
				if(isNullOrEmpty(wizardViewParser.getRazonFiscal()))
				{
					msjErrorRazonSocial = "* Razón Social.";
					resul = false;
				}
				else
				{
					if(!wizardViewParser.getRazonFiscal().matches(CFDIConstants.RAZON_REGEX))
					{
						msjErrorRazonSocial = 
								"*Formato de Razón Social incorrecto.";
						resul = false;
					}
				}
				if(isNullOrEmpty(wizardViewParser.getCalleFiscal()))
				{
					msjErrorCalleFiscal = "* Calle.";
					resul = false;
				}
				if(isNullOrEmpty(wizardViewParser.getCodigoPostalFiscal()))
				{
					msjErrorCPFiscal = "* Código Postal.";
					resul = false;
				}
				else
				{
					if(!wizardViewParser.getCodigoPostalFiscal().matches("\\d{5}"))
					{
						msjErrorCPFiscal = "* Código Postal incorrecto";
						resul = false;
					}
				}
				if(isNullOrEmpty(wizardViewParser.getPaisFiscal()))
				{
					msjErrorPaisFiscal ="* País.";
					resul = false;
				}
				if(isNullOrEmpty(wizardViewParser.getEstadoFiscal()))
				{
					msjErrorEstadoFiscal = "* Estado.";
					resul = false;
				}
				if(isNullOrEmpty(wizardViewParser.getMunicipioFiscal()))
				{
					msjErrorMunicipioFiscal = "* Municipio.";
					resul = false;
				}
			}			
		}		
		return resul;
	}
	
	private Boolean validarDireccionSucursal()
	{
		resetMsjErrorSucursar();
		Boolean resul = true;
		if( isNullOrEmpty(wizardViewParser.getCalleSucursal()) 		  	&&
			isNullOrEmpty(wizardViewParser.getCodigoPostalSucursal()) 	&&
			isNullOrEmpty(wizardViewParser.getPaisSucursal()) 			&&
			isNullOrEmpty(wizardViewParser.getEstadoSucursal())			&&
			isNullOrEmpty(wizardViewParser.getMunicipioSucursal()))
		{
			resetMsjErrorSucursar();
		}	
		else			
		{
			if(isNullOrEmpty(wizardViewParser.getNombreSucursal()))
			{
				msjErrorNameSucursal = "Debe especificar el nombre de sucursal";
				resul = false;
			}
			if(isNullOrEmpty(wizardViewParser.getCalleSucursal()))
			{ 
				msjErrorCalleSucursal = "* Calle";
				resul = false;
			}
			if(isNullOrEmpty(wizardViewParser.getCodigoPostalSucursal()))
			{ 
				msjErrorCPSucursal = "* Código postal";
				resul = false;
			}
			else
			{
				if(!wizardViewParser.getCodigoPostalSucursal().matches("\\d{5}"))
				{
					msjErrorCPSucursal = "* Código Postal incorrecto.";
					resul = false;
				}
			}
			if(isNullOrEmpty(wizardViewParser.getPaisSucursal()))
			{ 
				msjErrorPaisSucursal = "* Pais";
				resul = false;
			}
			if(isNullOrEmpty(wizardViewParser.getEstadoSucursal()))
			{ 
				msjErrorEstadoSucursal = "* Estado";
				resul = false;
			}
			if(isNullOrEmpty(wizardViewParser.getMunicipioSucursal()))
			{ 
				msjErrorMunicipioSucursal = "* Municipio";
				resul = false;
			}			
		}
		return resul;		
	}
	
	private Boolean isNullOrEmpty(String contenido)
	{		
		if((contenido == null)|| (contenido.isEmpty()))
		{
			return true;
		}
		return false;
	}
	
	private void resetMsjErrorFiscal()
	{		
		msjErrorRfc = null;
		msjErrorRazonSocial = null;
		msjErrorCalleFiscal = null;		
		msjErrorEstadoFiscal = null;
		msjErrorPaisFiscal = null;
		msjErrorCPFiscal = null;
		msjErrorMunicipioFiscal = null;
	}		
	
	private void resetMsjErrorSucursar()
	{
		msjErrorNameSucursal = null;
		msjErrorCalleSucursal = null;
		msjErrorCPSucursal = null;
		msjErrorPaisSucursal = null;
		msjErrorEstadoSucursal = null;
		msjErrorMunicipioSucursal = null;
	}
	
	private void retrieveInitialBusinessInfo()
	{
		businessNameMsjError = null;
		passKeyMsjError = null;
		cerMsjError = null;
		keyMsjError = null;		
		lblCer = "";
		urlCer = "";
		lblFechaCad = "";
		urlKey = "";				
	}	
	
	@GlobalCommand	
	public void wizardHideGiroPopUp()
	{
		if(window != null)
		{
			window.setVisible(false);
			window = null;
		}
	}
	
	/*-----Giro del negocio-----*/
	@GlobalCommand
	@NotifyChange({"nameGiros"})
	public void processGiros(@BindingParam("listGiros") List<WrapperGiros> listGirosSelected )
	{
		boolean primerItem = true;
		listGiros = new ArrayList<WrapperGiros>();		
		nameGiros = "";
		listGiros = listGirosSelected;		
		for(WrapperGiros current : listGirosSelected)
		{
			if(primerItem)
			{
				nameGiros = current.getNombreGiro();
			}
			else
			{
				nameGiros = nameGiros + " , " + current.getNombreGiro();
			}
			primerItem = false;
		}		
		wizardViewParser.setListGirosSelected(listGirosSelected);
	} 
}
